package com.uduemc.biso.node.web.scheduled;

import java.io.IOException;
import java.util.List;

import javax.annotation.Resource;

import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.uduemc.biso.core.extities.pojo.ICP35;
import com.uduemc.biso.core.utils.RedisUtil;
import com.uduemc.biso.node.core.entities.HDomain;
import com.uduemc.biso.node.core.property.GlobalProperties;
import com.uduemc.biso.node.web.api.config.SpringContextUtil;
import com.uduemc.biso.node.web.api.service.DomainService;
import com.uduemc.biso.node.web.component.CenterFunction;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;

@Component
@Slf4j
public class ICPScheduled {

	@Resource
	private SpringContextUtil springContextUtil;

	@Resource
	private RedisUtil redisUtil;

	@Resource
	private GlobalProperties globalProperties;

	@Resource
	private CenterFunction centerFunction;

	@Resource
	private ObjectMapper objectMapper;

	/**
	 * 每8分整点执行一次 计划任务，未进行审核状态的域名
	 */
	@Async
	@Scheduled(cron = "0 0/8 * * * ?")
	void status0() {
		// 获取数据库中绑定的域名
		List<HDomain> listHDomain = null;
		try {
			listHDomain = list((short) 0, 10);
		} catch (IOException e) {
			e.printStackTrace();
		}
		if (CollectionUtil.isEmpty(listHDomain)) {
			return;
		}

		for (HDomain hDomain : listHDomain) {
			String domainName = hDomain.getDomainName();
			// 获取备案信息数据
			if (StrUtil.isBlank(domainName)) {
				continue;
			}

			ICP35 icp35 = centerFunction.getIcpdomain(domainName);
			if (icp35 == null || icp35.getResult() == -1) {
				log.warn(domainName + " 未能通过35的备案系统获取到备案信息！");
				continue;
			}

			String remark;
			try {
				remark = objectMapper.writeValueAsString(icp35);
			} catch (JsonProcessingException e) {
				e.printStackTrace();
				continue;
			}

			if (icp35.getResult() == 1) {
				hDomain.setStatus((short) 1);
				hDomain.setRemark(remark);
			} else if (icp35.getResult() == 0) {
				hDomain.setStatus((short) 2);
				hDomain.setRemark("");
			} else {
				log.warn(domainName + " 获取的结果中存在未知的 result 的状态！ icp：" + remark);
				continue;
			}

			// 更新域名数据
			try {
				update(hDomain);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 每30分执行一次 计划任务，对已审核未通过的域名状态
	 */
	@Async
	@Scheduled(cron = "0 0/30 * * * ? ")
	void status2() {
		// 获取数据库中绑定的域名
		List<HDomain> listHDomain = null;
		try {
			listHDomain = list((short) 2, 10);
		} catch (IOException e) {
			e.printStackTrace();
		}
		if (CollectionUtil.isEmpty(listHDomain)) {
			return;
		}

		for (HDomain hDomain : listHDomain) {
			String domainName = hDomain.getDomainName();
			// 获取备案信息数据
			if (StrUtil.isBlank(domainName)) {
				continue;
			}

			ICP35 icp35 = centerFunction.getIcpdomain(domainName);
			if (icp35 == null || icp35.getResult() == -1) {
				log.warn(domainName + " 未能通过35的备案系统获取到备案信息！");
				continue;
			}

			String remark;
			try {
				remark = objectMapper.writeValueAsString(icp35);
			} catch (JsonProcessingException e) {
				e.printStackTrace();
				continue;
			}

			if (icp35.getResult() == 1) {
				hDomain.setStatus((short) 1);
				hDomain.setRemark(remark);
			} else if (icp35.getResult() == 0) {
				hDomain.setStatus((short) 2);
				hDomain.setRemark("");
			} else {
				log.warn(domainName + " 获取的结果中存在未知的 result 的状态！ icp：" + remark);
				continue;
			}

			// 更新域名数据
			try {
				update(hDomain);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	List<HDomain> list(short status, int pageSize) throws JsonParseException, JsonMappingException, JsonProcessingException, IOException {
		DomainService domainServiceImpl = springContextUtil.getBean("domainServiceImpl");

		long minId = 0;

		String redisKey = globalProperties.getRedisKey().getDomainStatusLastId(status);
		String value = (String) redisUtil.get(redisKey);

		Long lastId;
		if (StrUtil.isNotBlank(value)) {
			lastId = Long.valueOf(value);
			if (lastId != null && lastId.longValue() > minId) {
				minId = lastId.longValue();
			}
		}

		List<HDomain> listHDomain = domainServiceImpl.findByWhere(minId, status, pageSize);

		if (CollectionUtil.isEmpty(listHDomain) || listHDomain.size() < pageSize) {
			lastId = 0L;
		} else {
			lastId = listHDomain.get(listHDomain.size() - 1).getId();
			if (lastId == null || lastId.longValue() < 1) {
				lastId = 0L;
			}
		}

		redisUtil.set(redisKey, String.valueOf(lastId), 3600 * 12);

		return listHDomain;
	}

	void update(HDomain hDomain) throws JsonParseException, JsonMappingException, JsonProcessingException, IOException {
		DomainService domainServiceImpl = springContextUtil.getBean("domainServiceImpl");
		domainServiceImpl.updateItem(hDomain);
	}
}
